<!-- form表单，规则详解：https://www.cnblogs.com/kuki/p/15190259.html-->
<template>
	<div>
		<el-form
			:model="column"
			:rules="rules"
			ref="formColumn"
			label-width="120px"
			size="small"
			class="formColumn"
			:disabled="type == 'look'"
			:key="time"
		>
			<div
				v-for="(item, index) in config"
				:key="index"
				:style="{
					width: item.span == 2 ? '50%' : item.span == 3 ? '33%' : '100%',
					display: item.type == '' ? 'none' : 'inline-block',
				}"
			>
				<el-form-item
					:label="item.fieldCNName"
					:prop="item.fieldName"
					:style="{ display: item.type == '' ? 'none' : 'block' }"
				>
					<!-- 普通文本框 -->
					<el-input
						style="width: 100%"
						v-model="column[item.fieldName]"
						v-if="item.type == 'inputText'"
						:placeholder="item.placeholder ? item.placeholder : ''"
						:disabled="item.disabled ?? false"
						@change="
							(e) => {
								inputChange(e, item.fieldName)
							}
						"
					></el-input>

					<!-- textarea文本框 -->
					<el-input
						style="width: 100%"
						v-model="column[item.fieldName]"
						v-if="item.type == 'textarea'"
						type="textarea"
						:placeholder="item.placeholder ? item.placeholder : ''"
						:disabled="item.disabled ?? false"
					></el-input>

					<!-- 下拉框 -->
					<el-select
						v-model="column[item.fieldName]"
						placeholder="请选择"
						v-if="item.type == 'select'"
						style="width: 100%"
						:disabled="item.disabled ?? false"
						@change="
							(e) => {
								selectChange(e, item.fieldName)
							}
						"
					>
						<el-option
							:label="select.label"
							:value="select.value.toString()"
							v-for="(select, sIndex) in item.itemList"
							:key="sIndex"
						></el-option>
					</el-select>

					<!-- 日期 -->
					<el-date-picker
						:disabled="item.disabled ?? false"
						v-model="column[item.fieldName]"
						v-if="item.type == 'date' || item.type == 'datetime'"
						style="width: 100%"
						:type="item.type"
						placeholder="选择日期"
						:picker-options="pickerOptions"
						@change="
							(e) => {
								dateChange(e, item.fieldName, item.type)
							}
						"
					>
					</el-date-picker>

					<!-- 时间 时分秒 -->
					<el-time-picker
						:disabled="item.disabled ?? false"
						v-model="column[item.fieldName]"
						v-if="item.type == 'time'"
						style="width: 100%"
						format="HH:mm:ss"
						value-format="HH:mm:ss"
						placeholder="选择时间"
					>
					</el-time-picker>

					<!-- 日期范围 -->
					<el-date-picker
						:disabled="item.disabled ?? false"
						v-model="column[item.fieldName]"
						v-if="item.type == 'daterange' || item.type == 'datetimerange'"
						:type="item.type"
						unlink-panels
						range-separator="至"
						start-placeholder="开始日期"
						end-placeholder="结束日期"
						:picker-options="rangePickerOptions"
						@change="
							(e) => {
								dateRangeChange(e, item.fieldName, item.type)
							}
						"
					>
					</el-date-picker>

					<!-- switch -->
					<el-switch
						:disabled="item.disabled ?? false"
						v-model="column[item.fieldName]"
						v-if="item.type == 'switch'"
					></el-switch>

					<!-- checkbox -->
					<el-checkbox-group
						:disabled="item.disabled ?? false"
						v-model="column[item.fieldName]"
						v-if="item.type == 'checkbox'"
						@change="
							(e) => {
								checkChange(e, item.fieldName)
							}
						"
					>
						<el-checkbox
							:disabled="
								'ND' == checkItem && item.fieldName == 'options'
									? true
									: item.disabled ?? false
							"
							v-for="checkItem in item.itemList.map((t) => t.label)"
							:label="checkItem"
							:key="checkItem"
						>
							{{ checkItem }}
						</el-checkbox>
					</el-checkbox-group>

					<!-- radio -->
					<el-radio-group
						:disabled="item.disabled ?? false"
						v-model="column[item.fieldName]"
						v-if="item.type == 'radio'"
					>
						<el-radio
							:label="checkItem.value"
							v-for="(checkItem, index) in item.itemList"
							:key="index"
							>{{ checkItem.label }}</el-radio
						>
					</el-radio-group>

					<!-- inputNumber -->
					<el-input
						:disabled="item.disabled ?? false"
						style="width: 100%"
						type="number"
						:min="item.rules && item.rules.min ? item.rules.min : ''"
						:max="item.rules && item.rules.max ? item.rules.max : ''"
						v-model="column[item.fieldName]"
						v-if="item.type == 'inputNumber'"
					></el-input>

					<!-- upload 原来是图片上传功能，现在改成拍照功能，上传功能隐藏，今后需要在另外加type为uploadImg  -->
					<div style="display: none">
						<el-upload
							v-if="item.type == 'upload'"
							action="/ccdc/sys/common/upload"
							list-type="picture-card"
							:on-preview="handlePictureCardPreview"
							:file-list="fileList[item.fieldName]"
							:on-remove="
								(file, fileList) => {
									handleRemove(file, fileList, item.fieldName)
								}
							"
							:multiple="item.multiple"
							:on-exceed="
								(file, fileList) => {
									handleExceed(file, fileList, item.fieldName)
								}
							"
							:on-success="
								(file, fileList) => {
									handleChange(file, fileList, item.fieldName)
								}
							"
							:accept="item.accept"
							:limit="item.limit"
							:headers="headers"
						>
							<i class="el-icon-plus"></i>
						</el-upload>
					</div>
					<div v-if="item.type == 'upload'" style="display: inline-block">
						<div
							v-if="fileList[item.fieldName].length > 0"
							style="display: inline-block; float: left"
						>
							<div
								v-for="(imgItem, index) in fileList[item.fieldName].map(
									(t) => t.url
								)"
								v-bind:key="index"
								style="
									display: inline-block;
									float: left;
									margin-right: 10px;
									position: relative;
								"
							>
								<el-image
									style="width: 100px; height: 100px"
									:src="imgItem"
									:preview-src-list="fileList[item.fieldName].map((t) => t.url)"
								></el-image>
								<i
									class="el-icon-circle-close"
									title="点击删除图片"
									@click="deleteImg(imgItem, item.fieldName)"
									v-if="type != 'look'"
									style="
										position: absolute;
										right: 0;
										top: 0;
										color: #999;
										font-size: 20px;
										cursor: pointer;
									"
								></i>
							</div>
						</div>

						<el-button
							type="primary"
							size="mini"
							@click="showPhoto(item.fieldName)"
						>
							<i class="el-icon-plus"></i> 拍照
						</el-button>
					</div>
				</el-form-item>
			</div>

			<el-form-item>
				<slot></slot>
			</el-form-item>
			<el-form-item v-if="type != 'look'">
				<el-button v-if="showIdCard" type="primary" @click="readIdCard"
					>读 卡</el-button
				>

				<el-button type="primary" @click="submitForm('formColumn')"
					>提 交</el-button
				>
				<el-button @click="resetForm('formColumn')" v-if="type == 'add'"
					>重 置</el-button
				>
			</el-form-item>
		</el-form>

		<el-dialog :visible.sync="dialogVisible" append-to-body>
			<img width="100%" :src="dialogImageUrl" alt="" />
		</el-dialog>
	</div>
</template>

<script>
	import { PopupCommon } from "@/libs/popupCommon"
	import { Utility } from "@/libs/utility"
	import moment from "moment"
	// 字段对应规则
	let formRules = {}
	// 配置信息
	let formConfig = []
	let formColumn = {}
	let fileLists = {}
	export default {
		components: {},
		data() {
			return {
				// 当前正在编辑的拍照的字段
				curFieldName: "",
				dialogImageUrl: "",
				dialogVisible: false,
				headers: {},
				// 这里会动态创建字段（不知道一个页面会有多少个上传组件） 最终值：fileList:{file1:[{name:"xx",url:"xxx"}],file2:[{name:"xx",url:"xxx"}]}
				fileList: fileLists,
				time: "1",
				// 字段以及字段赋值
				column: formColumn,
				rules: formRules,
				config: formConfig,
				pickerOptions: {
					shortcuts: [
						{
							text: "今天",
							onClick(picker) {
								picker.$emit("pick", new Date())
							},
						},
						{
							text: "昨天",
							onClick(picker) {
								const date = new Date()
								date.setTime(date.getTime() - 3600 * 1000 * 24)
								picker.$emit("pick", date)
							},
						},
						{
							text: "一周前",
							onClick(picker) {
								const date = new Date()
								date.setTime(date.getTime() - 3600 * 1000 * 24 * 7)
								picker.$emit("pick", date)
							},
						},
					],
				},
				rangePickerOptions: {
					shortcuts: [
						{
							text: "最近一周",
							onClick(picker) {
								const end = new Date()
								const start = new Date()
								start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
								picker.$emit("pick", [start, end])
							},
						},
						{
							text: "最近一个月",
							onClick(picker) {
								const end = new Date()
								const start = new Date()
								start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
								picker.$emit("pick", [start, end])
							},
						},
						{
							text: "最近三个月",
							onClick(picker) {
								const end = new Date()
								const start = new Date()
								start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
								picker.$emit("pick", [start, end])
							},
						},
					],
				},
			}
		},
		props: [
			"formConfig",
			"type",
			"ReceiveData",
			"showTepe",
			"nidShow",
			"showIdCard",
		],
		methods: {
			// 删除图片
			deleteImg(item, fieldName) {
				console.log(item, fieldName)
				let imgList = JSON.parse(JSON.stringify(this.fileList[fieldName]))
				const itemIndex = imgList.findIndex((t) => t.url == item)
				imgList.splice(itemIndex, 1)
				this.fileList[fieldName] = imgList

				let value = this.column[fieldName].split(",")
				const fIndex = value.findIndex((t) => item.indexOf(t) != -1)
				value.splice(fIndex, 1)
				this.column[fieldName] = value.join(",")
			},
			readIdCard() {
				this.$emit("readIdCard", "")
			},

			/** 文件限制 */
			handleExceed(files, fileList, fieldName) {
				PopupCommon.notify(
					"info",
					`超过文件个数限制（${
						formConfig.find((t) => t.fieldName == fieldName).limit
					}），此次上传无效。`
				)
				console.log(
					`本次选择了 ${files.length} 个文件，共选择了 ${
						files.length + fileList.length
					} 个文件`
				)
			},
			/** 文件删除 */
			handleRemove(file, fileList, fieldName) {
				// 这里需要注意一下，新增的是：file.response.message，回显的是：file.name，不会有response
				const fileName =
					typeof file.response != "undefined"
						? file.response.message
						: file.name
				let value = this.column[fieldName].split(",")
				const fIndex = value.findIndex((t) => t == fileName)
				value = value.splice(fIndex + 1, 1)
				this.column[fieldName] = value.join(",")
				console.log(fileList)
			},
			/** 文件选择后的操作 */
			handleChange(file, fileList, fieldName) {
				console.log(fileList, this.column[fieldName])
				let value = this.column[fieldName]
				if (
					value == "" ||
					value == undefined ||
					typeof value == "undefined" ||
					value == null
				) {
					value = file.message
				} else {
					value = value + "," + file.message
				}
				this.column[fieldName] = value
				console.log(fileList, this.column[fieldName])
			},
			handlePictureCardPreview(file) {
				this.dialogImageUrl = file.url
				this.dialogVisible = true
			},
			inputChange(e, n) {
				this.$emit("formInputChange", {
					value: e,
					filedName: n,
					allData: this.column,
				})
			},
			selectChange(e, name) {
				// 这里返回当前select以及字段的值
				this.$emit("formSelectChange", {
					value: e,
					filedName: name,
					allData: this.column,
				})
			},
			checkChange(e, name) {
				// 这里返回当前checkbox以及字段的值
				this.$emit("formCheckChange", {
					value: e,
					filedName: name,
					allData: this.column,
				})
			},
			dateChange(value, columnName, type) {
				let format = ""
				if (type == "date") {
					format = "YYYY-MM-DD"
				} else if (type == "datetime") {
					format = "YYYY-MM-DD HH:mm:ss"
				} else if (type == "time") {
					format = "HH:mm:ss"
				}
				this.column[columnName] = moment(value).format(format)
			},
			dateRangeChange(value, columnName, type) {
				let format = type == "daterange" ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm:ss"
				if (value) {
					let newValue = []
					newValue.push(moment(value[0]).format(format))
					newValue.push(moment(value[1]).format(format))
					this.column[columnName] = newValue
				}
			},
			submitForm(formName) {
				let that = this
				this.$refs[formName].validate((valid) => {
					if (valid) {
						that.config.forEach((type) => {
							if (type.type == "checkbox") {
								if (that.column[type.fieldName].length > 0) {
									let newValue = []
									that.column[type.fieldName].forEach((t) => {
										newValue.push(type.itemList.find((b) => b.label == t).value)
									})
									this.column[type.fieldName] = newValue.join(",")
								} else {
									this.column[type.fieldName] = ""
								}
							}

							if (type.type == "time") {
								let fValue = this.column[type.fieldName]
								let finishV = fValue
								try {
									finishV = moment(fValue).format("HH:mm:ss")
									if (finishV.indexOf("date") != -1) {
										finishV = fValue
									}
								} catch (error) {
									finishV = fValue
								}
								this.column[type.fieldName] = finishV
							}

							// 时间范围处理
							if (type.type == "daterange" || type.type == "datetimerange") {
								console.log(this.column[type.fieldName])
								this.column[type.fieldNames[0]] = this.column[type.fieldName][0]
								this.column[type.fieldNames[1]] = this.column[type.fieldName][1]
								delete this.column[type.fieldName]
							}
						})
						that.$emit("submit", that.column)
					} else {
						return false
					}
				})
			},
			resetForm(formName) {
				console.log(formName, "............")
				this.$refs[formName].resetFields()
			},
			// 父组件改变子组件的值 (f是图片的字段名，v是图片的值，只用于图片)
			changeFormValue(d, f) {
				if (f) {
					fileLists[f] = []
					if (f) {
						const tempFileIds = d[f].split(",")
						console.log(tempFileIds, "tempFileIds...............")
						tempFileIds.forEach((item) => {
							if (item) {
								fileLists[f].push({
									name: item,
									url: Utility.getImgUrl(item),
								})
							}
						})
					}
					formColumn[f] = d[f]
				}
				console.log(d, "d.....")
				this.column = d
			},
			// 改变某个select组件的option的集合值
			changeSelectItemList(list, fieldName) {
				console.log(list, fieldName)
				console.log(formColumn, formConfig)
				formConfig.find((t) => t.fieldName == fieldName).itemList = list
			},
			getFormValue() {
				return this.column
			},
		},
		// 创建之前赋值规则会生效
		beforeCreate() {
			this.time = new Date().getTime()
			// 获取传递过来的规则
			const fcData = this.$options.propsData.formConfig
			if (typeof fcData == "undefined" || fcData.length < 1) {
				PopupCommon.notify("info", "请配置form字段及其规则")
				return
			}
			formConfig = fcData
			const fIndex = formConfig.findIndex((t) => t.fieldName == "optReason")
			if (fIndex > -1) {
				formConfig.splice(fIndex, 1)
			}
			if (
				this.$options.propsData.type == "edit" &&
				formConfig.findIndex((t) => t.fieldName == "optReason") == -1 &&
				this.$options.propsData.nidShow != "show"
			) {
				// 编辑增加操作原因字段
				// formConfig.push({
				// 	fieldName: "optReason",
				// 	fieldCNName: "操作原因",
				// 	filedValue: "",
				// 	type: "textarea",
				// 	rules: {
				// 		required: true,
				// 	},
				// })
			} else if (
				this.$options.propsData.type == "look" &&
				formConfig.findIndex((t) => t.fieldName == "optReason") == -1
			) {
				// 编辑增加操作原因字段
				// formConfig.push({
				// 	fieldName: "optReason",
				// 	fieldCNName: "操作原因",
				// 	filedValue: "",
				// 	disabled: true,
				// 	type: "textarea",
				// })
			}
			let label = ""
			// 规则  formRules
			fcData.forEach((t) => {
				// 下拉框的值这里要处理下：传过来的是id，这里要默认勾选得用name
				if (t.type == "checkbox") {
					console.log(t.type, "checkobx/////")
					if (t.filedValue && t.filedValue.indexOf(",") != -1) {
						t.filedValue = t.filedValue.split(",")
					}
					if (
						t.filedValue &&
						t.filedValue.length > 0 &&
						typeof t.filedValue == "object"
					) {
						let newCBValue = []
						t.filedValue.forEach((cb) => {
							try {
								label = t.itemList.find((cbv) => cbv.value == cb).label
							} catch (error) {
								console.log(error.message)
								label = ""
							}
							if (label) {
								newCBValue.push(label)
							}
						})
						formColumn[t.fieldName] = newCBValue
					} else {
						if (t.fieldName == "options" && t.fieldCNName == "选择项配置") {
							formColumn[t.fieldName] = ["ND"]
						} else {
							formColumn[t.fieldName] = []
						}
					}
				} else {
					if (t.type == "switch") {
						formColumn[t.fieldName] = t.filedValue == "1"
					} else if (t.type == "time") {
						const tempDate = t.filedValue.split(":")
						formColumn[t.fieldName] = new Date(
							2016,
							9,
							10,
							tempDate[0],
							tempDate[1],
							tempDate[2]
						)
					} else if (t.type == "upload") {
						fileLists[t.fieldName] = []
						if (t.filedValue) {
							const tempFileIds = t.filedValue.split(",")
							tempFileIds.forEach((item) => {
								if (item) {
									fileLists[t.fieldName].push({
										name: item,
										url: Utility.getImgUrl(item),
									})
								}
							})
						}
						formColumn[t.fieldName] = t.filedValue
					} else if (t.type == "select") {
						if (t.filedValue) {
							formColumn[t.fieldName] = t.filedValue.toString()
						} else {
							formColumn[t.fieldName] = t.filedValue
						}
					} else {
						formColumn[t.fieldName] = t.filedValue
					}
				}

				let itemRules = []
				if (t.rules) {
					Object.keys(t.rules).map((r) => {
						if (r == "required") {
							itemRules.push({
								required: true,
								message: t.fieldCNName + "不能为空",
							})
						}
						if (r == "len") {
							itemRules.push({
								len: t.rules["len"],
								message: `长度为${t.rules["len"]}`,
							})
						}
						if (r == "max") {
							itemRules.push({
								min: t.rules["min"],
								max: t.rules["max"],
								message: `长度在 ${t.rules["min"]} 到 ${t.rules["max"]} 个字符`,
							})
						}
						if (r == "type") {
							// 手机号码
							if (t.rules[r] == "phone") {
								itemRules.push({
									pattern: /^1[3-9]\d{9}$/,
									message: `请输入正确的手机号码`,
									trigger: "blur",
								})
							}
							// 座机
							if (t.rules[r] == "telphone") {
								itemRules.push({
									pattern: /\d{3,4}[-]\d{8}/,
									message: `请输入正确的座机号码：区号-号码`,
									trigger: "blur",
								})
							}
							// 身份证
							if (t.rules[r] == "idCard") {
								itemRules.push({
									pattern: /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/,
									message: `请输入正确身份证号码`,
									trigger: "blur",
								})
							}
							// 邮箱
							if (t.rules[r] == "email") {
								itemRules.push({
									type: "email",
									message: "请输入正确的邮箱地址",
									trigger: ["blur", "change"],
								})
							}
						}
					})
				}
				if (itemRules.length > 0) {
					formRules[t.fieldName] = itemRules
				}
			})
		},
		mounted() {
			// let projectTestperiod = window.sessionStorage.getItem("projectTestperiod")
			// if (projectTestperiod) {
			// 	projectTestperiod = JSON.parse(projectTestperiod)
			// 	// 上传时需要
			// 	this.headers = {
			// 		"X-Access-Token": localStorage.getItem("token"),
			// 		pmId: projectTestperiod.projectId,
			// 		expId: projectTestperiod.testId,
			// 		periodNo: projectTestperiod.periodId,
			// 	}
			// } else {
			// 	this.$router.replace({
			// 		name: "userLogin",
			// 	})
			// }
		},
		destroyed() {
			// 清空属性字段，解决切换页面无法输入的bug（因为保留了上一个页面的字段，导致字段不对称）
			// 字段对应规则
			formRules = {}
			// 配置信息
			formConfig = []
			formColumn = {}
		},
	}
</script>

<style></style>
